<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use App\Handlers\WeconHandler;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use SimpleSoftwareIO\QrCode\Facades\QrCode;

class DedustingDevice extends Model
{
    const STATUS_ONLINE = 1;
    const STATUS_OFFLINE = 2;
    const STATUS_FAULT = 3;
    const STATUS_REPAIR = 4;
    const STATUS_TEXT = ['1' => '在线', '2' => '离线', '3' => '故障', '4' => '维修'];

    const ONLINE_CACHE_KEY = 'dedusting_online_';   //在线状态缓存
    const DATA_CACHE_KEY = 'dedusting_data_';   //数据缓存
    const TOTAL_ALIVE_CACHE_KEY = 'dedusting_total_alive_';   //累计运行时间
    const NOW_ALIVE_CACHE_KEY = 'dedusting_now_alive_';   //当前运行时间

    const QRCODE_PATH = 'dedusting/devices/qrcode/';
    protected $table = 'xfy_dedusting_devices';

    public function repairs()
    {
        return $this->hasMany(DedustingRepair::class);
    }

    public static function genQrcode($code){
        self::delQrcode($code);
        $file = self::QRCODE_PATH.md5($code).'.png';
        $filePath = public_path($file);
        QrCode::encoding('UTF-8')->format('png')->size(250)->margin(1)->generate($code,$filePath);
        return url($file);
    }

    public static function delQrcode($code){
        $file = md5($code).'.png';
        $filePath = public_path(self::QRCODE_PATH.$file);
        if (is_file($filePath)) {
            unlink($filePath);
        }
    }

    public function owner()
    {
        return $this->belongsTo(DedustingUser::class, 'bind_user_id');
    }

    public static function userBind($code, $userId) {
        try {
            $device = self::where('code', $code)->whereNull('bind_user_id')->firstOrFail();
            $device->bind_user_id = $userId;

            if ($device->save()) {
                return $device;
            }
            return false;

        } catch (Exception $e) {
            throw new Exception('错误的设备码或设备已被绑定');
        }
    }

    /**
     * [statusAndAlive 监测状态并计算运行时长]
     * @param  string $value [description]
     * @return [type]        [description]
     */
    public static function statusAndAlive()
    {
        $second = 0;
        while ($second <= 59) {
            
            $devices = self::whereNotNull('machine_code')->pluck('id')->toArray();
            foreach ($devices as $id) {
                $cacheKey = self::DATA_CACHE_KEY.$id;
                $cacheData = Redis::get($cacheKey);
                if ($cacheData) {
                    $data = json_decode($cacheData,true);
                    $latestTime = $data['time'];

                    $redisStatusKey = self::ONLINE_CACHE_KEY.$id;
                    //最后一条超过30秒，定义为离线了
                    if ((time() - 30) > $latestTime) {
                        Redis::set($redisStatusKey, 0);

                        $nowAliveKey = self::NOW_ALIVE_CACHE_KEY.$id;
                        Redis::set($nowAliveKey, 0);

                    } else {
                        Redis::set($redisStatusKey, 1);

                        $totalAliveKey = self::TOTAL_ALIVE_CACHE_KEY.$id;
                        Redis::incr($totalAliveKey);
                        $nowAliveKey = self::NOW_ALIVE_CACHE_KEY.$id;
                        Redis::incr($nowAliveKey);
                    }
                }
            }

            sleep(1);
            $second++;
        }
    }
}